home *** CD-ROM | disk | FTP | other *** search
- /* ------------------------------------------------------------------------------
- #
- # Apple Macintosh Developer Technical Support
- #
- # AppleTalk GetZoneList Sample Application
- #
- # GetZoneList
- #
- # GetZoneList.c - C Source
- #
- # Copyright © 1988-90 Apple Computer, Inc.
- # All rights reserved.
- #
- # Versions: 1.00 November 1988
- # 1.01 October 1989
- # 1.02 May 1990
- # 1.03 June 1992
- # 1.04 July 1992
- #
- # Components: GetZoneList.c May 1, 1990
- # GetZoneList.p May 1, 1990
- # GetZoneList.r May 1, 1990
- # MakeFile May 1, 1990
- # UFailure.a November 1, 1988
- # UFailure.h November 1, 1988
- # UFailure.inc1.p November 1, 1988
- # UFailure.p November 1, 1988
- #
- # GetZoneList is a sample application that uses
- # AppleTalk ATP and ZIP to obtain a list of zones
- # on an AppleTalk internet.
- #
- # GetZoneList also demonstrates using a signal, or
- # failure-catching mechanism to recover from error
- # situations. Since C does not allow nested procedures
- # a la Pascal, a few modifications were made to incorporate
- # the failure handling and keep this sample fairly close in
- # design to the Pascal sample.
- # (Gee, thanks a lot M2 for using nested procs. - pvh)
- #
- # GetZoneList is based on DTS Sample.c. For more
- # description and explanation of the non-example
- # specific areas of this application, please refer to
- # either Sample.p or TESample.c.
- #
- ------------------------------------------------------------------------------ */
-
- #include <Limits.h>
- #include <Types.h>
- #include <QuickDraw.h>
- #include <Fonts.h>
- #include <Events.h>
- #include <Controls.h>
- #include <Windows.h>
- #include <Menus.h>
- #include <TextEdit.h>
- #include <Dialogs.h>
- #include <Packages.h>
- #include <Menus.h>
- #include <Devices.h>
- #include <Events.h>
- #include <Scrap.h>
- #include <Lists.h>
- #include <ToolUtils.h>
- #include <Memory.h>
- #include <SegLoad.h>
- #include <Errors.h>
- #include <Files.h>
- #include <OSUtils.h>
- #include <AppleTalk.h>
- #include <Traps.h>
- #include <DiskInit.h>
- #include <Script.h>
- #include <UFailure.h>
-
-
- typedef XCallParam *XCallParamPtr;
-
- #define kSysEnvironsVersion 1
- #define kOSEvent app4Evt /* event used by Multifinder */
- #define kSuspendResumeMessage 1 /* high byte of suspend/resume event message */
- #define kResumeMask 1 /* bit of message field for resume vs. suspend */
-
- #define kCR 13 /* carriage return character */
- #define kENTER 3 /* enter character */
- #define kScrollBarWidth 15 /* the width of the scrollbar in the list */
- #define kListInset -1 /* adjustment for list frame */
- #define kATPTimeOutVal 3 /* re-try ATP SendRequest every 3 seconds */
- #define kATPRetryCount 5 /* for five times */
- #define kZonesSize 578 /* size of buffer for zone names */
- #define kGZLCall 0x08000000 /* GetZoneList indicator */
- #define kZIPSocket 6 /* the Zone Information Protocol socket */
- #define kMoreZones 0xFF000000 /* mask to see if more zones to come */
- #define kZoneCount 0x0000FFFF /* mask to count zones in buffer */
- #define kHilite 1 /* hilite value for button control */
- #define kDeHilite 0 /* dehilite value for button control */
- #define kHiliteDelay 8 /* time in ticks to leave button hilited */
-
- #define kMinHeap (29 * 1024)
- #define kMinSpace (20 * 1024)
-
- #define sErrStrings 128 /* error string STR# */
- #define eStandardErr 1
- #define eWrongMachine 2
- #define eSmallSize 3
- #define eNoMemory 4
- #define eAppleTalk 5
- #define eNoZones 6
-
- #define rAboutAlert 128 /* about alert */
- #define rZoneDialog 129 /* zone list dialog */
- #define dZoneList 2 /* user item that is zone list */
- #define dDefault 3 /* user item that is default indicator */
- #define rUserAlert 130 /* error alert */
-
- #define rMenuBar 128 /* application's menu bar */
-
- #define mApple 128 /* Apple menu */
- #define iAbout 1
-
- #define mFile 129 /* File menu */
- #define iNew 1
- #define iClose 4
- #define iQuit 12
-
- #define mEdit 130 /* Edit menu */
- #define iUndo 1
- #define iCut 3
- #define iCopy 4
- #define iPaste 5
- #define iClear 6
-
- /* kDITop and kDILeft are used to locate the Disk Initialization dialogs. */
- #define kDITop 0x0050
- #define kDILeft 0x0070
-
-
- /* Globs */
- SysEnvRec gMac; /* set up by Initialize */
- Boolean gHasWaitNextEvent; /* set up by Initialize */
- Boolean gInBackground; /* maintained by Initialize and DoEvent */
- XCallParamPtr gXPBPBPtr; /* structure for Phase 2 NBP lookups */
- /* needs to be global for failure handling */
-
-
- ListHandle gList; /* the list to be filled with zone names */
-
- extern void _DataInit();
-
- /* globals added for C sample use as the Pascal
- example used those horrid :-) nested procedures! */
- ATPPBPtr gATPPBPtr; /* the parameter block for GetZoneList call */
- Ptr gZones; /* the data buffer for GetZoneList call */
- DialogPtr gErrDlg; /* Dialog used for displaying zone list */
-
-
- /* Check to see if a given trap is implemented. This is only used by the
- Initialize routine in this program, so we put it in the Initialize segment.
- The recommended approach to see if a trap is implemented is to see if
- the address of the trap routine is the same as the address of the
- Unimplemented trap. */
- /* 1.02 - Needs to be called after call to SysEnvirons so that it can check
- if a ToolTrap is out of range of a pre-MacII ROM. */
-
- #pragma segment Initialize
- Boolean TrapAvailable(tNumber,tType)
- short tNumber;
- TrapType tType;
- {
- if ( ( tType == (unsigned char) ToolTrap ) &&
- ( gMac.machineType > envMachUnknown ) &&
- ( gMac.machineType < envMacII ) ) { /* it's a 512KE, Plus, or SE */
- tNumber = tNumber & 0x03FF;
- if ( tNumber > 0x01FF ) /* which means the tool traps */
- tNumber = _Unimplemented; /* only go to 0x01FF */
- }
- return NGetTrapAddress(tNumber, tType) != NGetTrapAddress(_Unimplemented, ToolTrap);
- } /*TrapAvailable*/
-
-
- #pragma segment Main
- void FailOSErrMsg(result, message)
- short result;
- short message;
- {
- if (result != noErr)
- Failure(result, message);
- } /* SignalOSErrMsg */
-
-
- #pragma segment Main
- void FailnilMsg(p, message)
- Ptr p;
- short message;
- {
- if (p == nil)
- Failure(memFullErr, message);
- } /* FailNILMsg */
-
-
- #pragma segment Main
- void AlertUser(error, message)
-
- /* Display an alert to inform the user of an error. Message acts as an
- index into a STR# resource of error messages. if no message is given,
- i.e. = 0, then use a standard message. if error is not noErr then
- display it as well. */
-
- short error;
- long message;
- {
- Str255 msg1, msg2;
- short itemHit;
-
- if (message <= 0L) message = eStandardErr;
- GetIndString(msg1, sErrStrings, message);
- if (error == noErr)
- msg2[0] = '';
- else
- NumToString(error, msg2);
- ParamText(msg1, msg2, "\p", "\p");
- itemHit = Alert(rUserAlert, nil);
- } /* AlertUser */
-
-
- #pragma segment Main
- Boolean IsDAWindow(window)
- WindowPtr window;
- {
- if (window == nil)
- return (false);
- else /* DA windows have negative windowKinds */
- return ((WindowPeek) window)->windowKind < 0;
- } /* IsDAWindow */
-
-
- #pragma segment Main
- Boolean IsAppWindow(window)
- WindowPtr window;
- {
- short windowKind;
-
- if ( window == nil )
- return false;
- else { /* application windows have windowKinds >= userKind (8) or dialogKind (2) */
- windowKind = ((WindowPeek) window)->windowKind;
- return (windowKind >= userKind) || (windowKind == dialogKind);
- }
- } /* IsAppWindow */
-
-
- #pragma segment Main
- void ZoneListCleanUp()
- {
- if (gATPPBPtr != nil)
- DisposePtr((Ptr)gATPPBPtr); /* get rid of pb block */
- if (gZones != nil)
- DisposePtr(gZones); /* and buffer */
- } /* ZoneListCleanUp */
-
-
- #pragma segment Main
- pascal void HandleZoneListErr(short error, long message)
- {
- #pragma unused (error, message)
-
- ZoneListCleanUp(); /* get rid of allocated junk */
- } /* HandleZoneListErr */
-
-
- #pragma segment Main
- void BuildZoneList()
-
- /*
- * Create the list of zones on the network. Find a bridge to talk to , if one is
- * present, then ask it for zone names. Add the names to the list in the dialog.
- */
-
- {
- BDSElement dBDS; /* the BDS for GetZoneList call */
- Ptr dCurr; /* the data buffer for GetZoneList call */
- short dIndex, dCount;
- short ignore;
- Cell cSize;
- FailInfo fi;
- short nodeNetAddress, bridgeNode;
-
- gATPPBPtr = nil; /* init some important variables*/
- gZones = nil;
-
- CatchCFailures(&fi, HandleZoneListErr);
-
- gATPPBPtr = (ATPPBPtr)NewPtr(sizeof(ATPParamBlock));
- FailnilMsg(gATPPBPtr, eNoMemory);
- gZones = NewPtr(kZonesSize);
- FailnilMsg(gZones, eNoMemory);
- dBDS.buffSize = kZonesSize; /* set up BDS */
- dBDS.buffPtr = gZones;
-
- gATPPBPtr->ATPatpFlags = 0;
-
- /*
- * get network address of node & node ID of bridge (if any)
- */
- FailOSErrMsg(GetNodeAddress(&ignore, &nodeNetAddress), eAppleTalk);
- bridgeNode = GetBridgeAddress();
-
- /*
- * test to see if bridge node fails. If so, no internet.
- */
- if (bridgeNode == 0)
- Failure(0, eNoZones); /* bail if no zones present */
-
- gATPPBPtr->ATPaddrBlock.aNet = nodeNetAddress;
- gATPPBPtr->ATPaddrBlock.aNode = bridgeNode; /* get node of bridge */
- gATPPBPtr->ATPaddrBlock.aSocket = kZIPSocket; /* the socket we want */
- gATPPBPtr->ATPreqLength = 0;
- gATPPBPtr->ATPreqPointer = nil;
- gATPPBPtr->ATPbdsPointer = (Ptr) &dBDS;
- gATPPBPtr->ATPnumOfBuffs = 1;
- gATPPBPtr->ATPtimeOutVal = kATPTimeOutVal;
- gATPPBPtr->ATPretryCount = kATPRetryCount;
-
- dIndex = 1;
- dCount = 0;
- SetPt(&cSize, 0, 0); /* we always stuff into first */
-
- do {
- gATPPBPtr->ATPuserData = kGZLCall + dIndex; /* indicate GetZoneList request */
- FailOSErrMsg(PSendRequest(gATPPBPtr, false), eAppleTalk); /* send sync request */
-
- dCount = dCount + dBDS.userBytes & kZoneCount; /* find out how many returned */
- dCurr = gZones; /* put current pointer at start */
- do { /* get each zone */
- ignore = LAddRow(1, 0, gList); /* create new cell at start */
- LSetCell((Ptr)dCurr + 1L, (short) *dCurr, cSize, gList); /* stuff in zone */
- dCurr = (Ptr)(dCurr + *dCurr + 1 ); /* bump up current pointer */
- dIndex = dIndex + 1; /* increment which zone */
- } while(! (dIndex > dCount));
-
- } while ((dBDS.userBytes & kMoreZones) == 0); /* keep going until none left */
-
- ZoneListCleanUp();
-
- Success(&fi);
- } /* BuildZoneList */
-
-
- #pragma segment Main
- void ZoneListCleanUpPhase2()
- {
- if (gXPBPBPtr != nil)
- DisposePtr((Ptr)gXPBPBPtr); /* get rid of pb block */
- if (gZones != nil)
- DisposePtr(gZones); /* and buffer */
- } /* ZoneListCleanUpPhase2 */
-
- #pragma segment Main
- void BuildZoneListPhase2()
-
- /* Create the list of zones on the network. Find a bridge to talk to , if one is
- present, then ask it for zone names. Add the names to the list in the dialog. */
-
- {
- Ptr dCurr; /* the data buffer for GetZoneList call */
- short dIndex, dCount;
- short ignore;
- Cell cSize;
- FailInfo fi;
-
- short xppDriverRefNum;
-
- gXPBPBPtr = nil; /* init some important variables*/
- gZones = nil;
-
- CatchCFailures(&fi, HandleZoneListErr);
-
- /* Get network address of bridge. If zero, no internet. */
- if (GetBridgeAddress() == 0)
- Failure(0, eNoZones); /* bail if no zones present */
-
- /* get a hold of the XPP driver reference number-this is the safest way */
- FailOSErrMsg(OpenDriver("\p.XPP", &xppDriverRefNum), eAppleTalk);
-
- gXPBPBPtr = (XCallParamPtr)NewPtr(sizeof(XCallParam));
- FailnilMsg(gXPBPBPtr, eNoMemory);
- gZones = NewPtr(kZonesSize);
- FailnilMsg(gZones, eNoMemory);
-
- gXPBPBPtr->zipInfoField[0] = 0; /* ALWAYS 0 on first call. has state info on subsequent calls */
- gXPBPBPtr->zipInfoField[1] = 0; /* ALWAYS 0 on first call. has state info on subsequent calls */
- gXPBPBPtr->zipLastFlag = 0;
-
- gXPBPBPtr->ioRefNum = xppDriverRefNum;
- gXPBPBPtr->csCode = xCall;
- gXPBPBPtr->xppSubCode = zipGetZoneList;
- gXPBPBPtr->xppTimeout = kATPTimeOutVal;
- gXPBPBPtr->xppRetry = kATPRetryCount;
- gXPBPBPtr->zipBuffPtr = (Ptr) gZones;
-
- dIndex = 1;
- dCount = 0;
- SetPt(&cSize, 0, 0); /* we always stuff into first */
-
- do {
- FailOSErrMsg(PBControl((ParmBlkPtr) gXPBPBPtr, false), eAppleTalk); /* send sync control call */
-
- dCount = dCount + gXPBPBPtr->zipNumZones; /* find out how many returned */
- dCurr = gZones; /* put current pointer at start */
- do { /* get each zone */
- ignore = LAddRow(1, 0, gList); /* create new cell at start */
- LSetCell((Ptr)dCurr + 1L, (short) *dCurr, cSize, gList); /* stuff in zone */
- dCurr = (Ptr)(dCurr + *dCurr + 1 ); /* bump up current pointer */
- dIndex = dIndex + 1; /* increment which zone */
- } while(! (dIndex > dCount));
-
- } while (gXPBPBPtr->zipLastFlag == 0); /* keep going until none left */
-
- ZoneListCleanUpPhase2();
-
- Success(&fi);
- } /* BuildZoneList */
-
- #pragma segment Main
- pascal void ZoneListDraw(dlg, item)
- DialogPtr dlg;
- short item;
- {
-
- /* The user item void for the zone list user item and default
- box user item in the dialog. Draw the list and the frame that goes with it.
- Draw the default box around the OK button */
-
- GrafPtr port;
- short kind;
- Handle h;
- Rect r;
- PenState ps;
-
- GetPort(&port); /* save old port */
- SetPort(dlg); /* make dialog port */
- switch (item) {
- case dZoneList:
- LUpdate(dlg->visRgn, gList); /* re-draw list */
- GetDialogItem(dlg, dZoneList, &kind, &h, &r);
- InsetRect(&r, kListInset, kListInset);
- FrameRect(&r); /* re-draw frame */
- break;
- case dDefault:
- GetDialogItem(dlg, dDefault, &kind, &h, &r);
- GetPenState(&ps);
- PenNormal(); /* always be on the defensive */
- PenSize(3, 3);
- InsetRect(&r, -4, -4);
- FrameRoundRect(&r, 16, 16); /* draw default box */
- SetPenState(&ps);
- break;
- }
- SetPort(port); /* restore old port */
- } /* ZoneListDraw */
-
-
- #pragma segment Main
- pascal Boolean ListFilter (dlg, event, item)
- DialogPtr dlg;
- EventRecord *event;
- short *item;
- {
-
- /* Passed as parameter to ModalDialog. Handle key presses and mouse clicks
- from the user. Do all the right default actions since we override them
- by virtue of our existence. */
-
- GrafPtr port;
- Point loc;
- short kind;
- Handle h;
- Rect r;
- Boolean ignore;
- char key;
- long finalTicks;
-
- Boolean returnValue;
-
- returnValue = false; /* always default false */
-
- switch (event->what) {
- case keyDown: /* check for <cr> or <enter> */
- case autoKey:
- key = (char) event->message;
- if (key == kCR || key == kENTER) { /* it was a <cr> or <enter> */
- GetDialogItem(dlg, ok, &kind, &h, &r);
- HiliteControl((ControlHandle)h, kHilite);
- Delay(kHiliteDelay, &finalTicks);
- HiliteControl((ControlHandle)h, kDeHilite);
- returnValue = true; /* so we handle it */
- *item = 1; /* and make the first item hit */
- }
- break;
- case mouseDown: /* we want mouseDowns */
- GetPort(&port);
- SetPort(dlg);
- loc = event->where;
- GlobalToLocal(&loc); /* find where clicked */
- GetDialogItem(dlg, dZoneList, &kind, &h, &r); /* get rect for list */
- if (PtInRect(loc, &r)) { /* if clicked inside… */
- returnValue = true; /* we take care of it */
- ignore = LClick(loc, event->modifiers, gList); /* by passing click to list */
- }
- SetPort(port);
- break;
- }
- return (returnValue);
- } /* ListFilter */
-
-
- #pragma segment Main
- void CleanUp_DoZoneList()
- {
- if (gList != nil)
- LDispose(gList); /* get rid of list */
- if (gErrDlg != nil)
- DisposeDialog(gErrDlg); /* get rid of dialog */
- } /* CleanUp_DoZoneList */
-
-
- #pragma segment Main
- pascal void HandleErr_DoZoneList(short error, long message)
- {
- #pragma unused (error, message)
-
- CleanUp_DoZoneList(); /* release junk */
- } /* HandleErr_DoZoneList */
-
-
- #pragma segment Main
- void DoZoneList()
-
- /* Put up a modal dialog that shows a list of the zones on the net. Create the dialog
- and list, call BuildZoneList to fill it, then wait for the user to click OK. */
-
- {
- DialogPtr dlg;
- short item, kind;
- Handle h;
- Rect r, rView, dataBounds;
- Cell cSize;
- FailInfo fi;
- short hor, ver;
- ModalFilterUPP mfUPP;
-
- gList = nil; /* init some important variables */
- dlg = nil;
-
- CatchCFailures(&fi, HandleErr_DoZoneList);
-
- dlg = GetNewDialog(rZoneDialog, nil, (WindowPtr)-1); /* create dialog */
- SetPort(dlg);
-
- gErrDlg = dlg;
-
- FailnilMsg(dlg, eNoMemory);
-
- /* We center the dialog horizontally and position it vertically one-third the
- distance from the menu bar to the bottom of the main device. We do not
- check for the dialog extending past the bottom of the device because we
- know the dialog is not that big. You may wish to make that check. */
-
- hor = dlg->portRect.right - dlg->portRect.left;
- ver = dlg->portRect.bottom - dlg->portRect.top;
-
- hor = ((qd.screenBits.bounds.right - qd.screenBits.bounds.left) - hor) / 2;
- ver = (((qd.screenBits.bounds.bottom - qd.screenBits.bounds.top) - ver - GetMBarHeight()) / 3) + GetMBarHeight();
-
- MoveWindow(dlg, hor, ver, false);
-
- GetDialogItem(dlg, dDefault, &kind, &h, &r);
- SetDialogItem(dlg, dDefault, kind, (Handle) ZoneListDraw, &r);
- GetDialogItem(dlg, dZoneList, &kind, &h, &r);
- SetDialogItem(dlg, dZoneList, kind, (Handle) ZoneListDraw, &r); /* connect drawing void */
- rView = r;
- rView.right -= kScrollBarWidth; /* adjust rectangle for scroll */
- SetRect(&dataBounds, 0, 0, 1, 0); /* init to one-wide list */
- SetPt(&cSize, 0, 0);
- gList = LNew(&rView, &dataBounds, cSize, 0, (WindowPtr)dlg,
- false, false, false, true); /* create with vertical scroll */
- FailnilMsg(gList, eNoMemory);
-
- /* changes for Phase 2 - pvh 8/6/89 */
- /* this is the easiest check for Phase 2's existence */
- if(gMac.atDrvrVersNum >= 53)
- BuildZoneListPhase2(); /* put the stuff into the list */
- else
- BuildZoneList(); /* put the stuff into the list */
-
- SetPt(&cSize, 0, 0);
- LSetSelect(true, cSize, gList); /* select the first guy */
- LSetDrawingMode(true, gList); /* turn on the list */
- ShowWindow(dlg); /* turn on the dialog */
-
- mfUPP = NewModalFilterProc(ListFilter);
- do {
- ModalDialog(mfUPP, &item); /* accept events */
- } while (item != ok); /* until he presses 'ok' */
- DisposeRoutineDescriptor(mfUPP);
-
- CleanUp_DoZoneList();
-
- Success(&fi);
- } /* DoZoneList */
-
-
- #pragma segment Main
- Boolean DoCloseWindow(window)
- WindowPtr window;
- {
- Boolean functionValue = true;
-
- if (IsDAWindow(window))
- CloseDeskAcc((short) ((WindowPeek)window)->windowKind);
- if (IsAppWindow(window))
- CloseWindow(window);
-
- return(functionValue);
- } /* DoCloseWindow */
-
-
- #pragma segment Initialize
- pascal void HandleErr_Initialize(error, message)
- short error;
- long message;
- {
- if (error > 0)
- AlertUser(0, error);
- else
- AlertUser(error, message);
- ExitToShell();
- } /* HandleErr_Initialize */
-
-
- #pragma segment Initialize
- void Initialize()
- {
- Handle menuBar;
- OSErr ignoreError;
- long total, contig;
- Boolean ignoreResult;
- EventRecord event;
- short count;
- FailInfo fi;
-
- gHasWaitNextEvent = TrapAvailable(_WaitNextEvent, ToolTrap);
- gInBackground = false;
-
- InitGraf(&qd.thePort);
- InitFonts();
- InitWindows();
- InitMenus();
- TEInit();
- InitDialogs(nil);
- InitCursor();
-
- /* get MultiFinder started */
- for (count=1;count<3;count++)
- ignoreResult = EventAvail(everyEvent, &event);
-
- CatchCFailures(&fi, HandleErr_Initialize);
-
- FailOSErrMsg(MPPOpen(), eAppleTalk);
- FailOSErrMsg(ATPLoad(), eAppleTalk);
-
- ignoreError = SysEnvirons(kSysEnvironsVersion, &gMac);
- if (gMac.machineType < 0)
- Failure(0, eWrongMachine);
-
- if (GetApplLimit() - ApplicationZone() < kMinHeap)
- Failure(0, eSmallSize);
-
- PurgeSpace(&total, &contig);
- if (total < kMinSpace)
- Failure(0, eNoMemory);
-
- menuBar = GetNewMBar(rMenuBar); /* read menus into menu bar */
- FailnilMsg(menuBar, eNoMemory);
-
- SetMenuBar(menuBar); /* install menus */
- DisposeHandle(menuBar);
- AppendResMenu(GetMenuHandle(mApple), 'DRVR'); /* add DA names to Apple menu */
- DrawMenuBar();
-
- Success(&fi);
- } /* Initialize */
-
-
- #pragma segment Main
- void Terminate()
- {
- WindowPtr aWindow;
- Boolean closed;
-
- closed = true;
- do {
- aWindow = FrontWindow(); /* get the current front window */
- if (aWindow != nil)
- closed = DoCloseWindow(aWindow); /* close this window */
- } while ((closed) && (aWindow != nil)); /* do all windows */
- if (closed)
- ExitToShell(); /* exit if no cancellation */
- } /* Terminate */
-
-
- #pragma segment Main
- void AdjustMenus()
- {
- WindowPtr window;
- MenuHandle menu;
-
- window = FrontWindow();
-
- menu = GetMenuHandle(mFile);
- if (IsDAWindow(window)) /* we can allow desk accessories to be closed from the menu */
- EnableItem(menu, iClose);
- else
- DisableItem(menu, iClose); /* but not our traffic light window */
-
- menu = GetMenuHandle(mEdit);
- if (IsDAWindow(window)) { /* a desk accessory might need the edit menu */
- EnableItem(menu, iUndo);
- EnableItem(menu, iCut);
- EnableItem(menu, iCopy);
- EnableItem(menu, iPaste);
- EnableItem(menu, iClear);
- }
- else { /* but we know we do not */
- DisableItem(menu, iUndo);
- DisableItem(menu, iCut);
- DisableItem(menu, iCopy);
- DisableItem(menu, iClear);
- DisableItem(menu, iPaste);
- }
- } /* AdjustMenus */
-
-
- pascal void HandleMenu(short error, long message)
- {
- #pragma unused (error, message)
-
- HiliteMenu(0); /* unhighlight what MenuSelect (or MenuKey) hilited */
- } /* HandleMenu */
-
-
- #pragma segment Main
- void DoMenuCommand(menuResult)
- long menuResult;
- {
- short menuID; /* the resource ID of the selected menu */
- short menuItem; /* the item number of the selected menu */
- short itemHit;
- Str255 daName;
- short daRefNum;
- Boolean handledByDA ;
- Boolean ignore;
- FailInfo fi;
-
- CatchCFailures(&fi, (HandlerFuncPtr) HandleMenu);
-
- menuID = HiWord(menuResult); /* use built-ins (for efficiency)... */
- menuItem = LoWord(menuResult); /* to get menu item number and menu number */
- switch (menuID) {
- case mApple:
- switch (menuItem) {
- case iAbout: /* bring up alert for About */
- itemHit = Alert(rAboutAlert, nil);
- break;
- default: /* all non-About items in this menu are DAs */
- GetMenuItemText(GetMenuHandle(mApple), menuItem, daName);
- daRefNum = OpenDeskAcc(daName);
- break;
- }
- break;
- case mFile:
- switch (menuItem) {
- case iNew:
- DoZoneList();
- break;
- case iClose:
- ignore = DoCloseWindow(FrontWindow());
- break;
- case iQuit:
- Terminate();
- break;
- }
- break;
- case mEdit: /* call SystemEdit for DA editing & Multifinder */
- handledByDA = SystemEdit(menuItem-1); /* since we don't do any editing */
- break;
- }
-
- HiliteMenu(0); /* cleanup */
-
- Success(&fi);
- } /* DoMenuCommand */
-
-
- #pragma segment Main
- pascal void HandleErr_DoEvent(error, message)
- short error;
- long message;
- {
- if (error > 0)
- AlertUser(0, error);
- else
- AlertUser(error, message);
- ExitToShell();
- } /* HandleErr_DoEvent */
-
-
- #pragma segment Main
- void DoEvent(event)
- EventRecord event;
- {
- short part;
- WindowPtr window;
- char key;
- FailInfo fi;
- Point aPoint;
- OSErr err;
-
- CatchCFailures(&fi, (HandlerFuncPtr) HandleErr_DoEvent);
-
- switch (event.what) {
- case mouseDown:
- part = FindWindow(event.where, &window);
- switch (part) {
- case inMenuBar: /* process the menu command */
- AdjustMenus();
- DoMenuCommand(MenuSelect(event.where));
- break;
- case inSysWindow: /* let the system handle the mouseDown */
- SystemClick(&event, window);
- break;
- case inContent:
- break;
- case inDrag:
- break;
- case inGrow:
- break;
- case inZoomIn:
- case inZoomOut:
- break;
- }
- break;
- case keyDown: /* check for menukey equivalents */
- case autoKey:
- key = event.message & charCodeMask;
- if (event.modifiers & cmdKey) { /* Command key down */
- if (event.what == keyDown) {
- AdjustMenus(); /* enable/disable/check menu items properly */
- DoMenuCommand(MenuKey(key));
- }
- }
- break;
- /* call DoActivate with the window and... */
- case activateEvt:
- break;
- case updateEvt:
- break;
- /* It is not a bad idea to at least call DIBadMount in response
- to a diskEvt, so that the user can format a floppy. */
- case diskEvt:
- if (HiWord(event.message) != noErr) {
- SetPt(&aPoint, kDILeft, kDITop);
- err = DIBadMount(aPoint, event.message);
- }
- case kOSEvent:
- switch ((event.message >> 24) & 0x0FF) { /* high byte of message */
- case kSuspendResumeMessage:
- gInBackground = event.message & kResumeMask;
- break;
- }
- break;
- }
- Success(&fi);
- } /* DoEvent */
-
-
- #pragma segment Main
- void EventLoop()
- {
- RgnHandle cursorRgn;
- Boolean gotEvent;
- EventRecord event;
-
- cursorRgn = NewRgn(); /* we’ll pass WNE an empty region the 1st time thru */
-
- do {
- if (gHasWaitNextEvent) /* put us 'asleep' forever under Multifinder */
- gotEvent = WaitNextEvent(everyEvent, &event, LONG_MAX, cursorRgn);
- else {
- SystemTask(); /* must be called if using GetNextEvent */
- gotEvent = GetNextEvent(everyEvent, &event);
- }
- if (gotEvent) {
- DoEvent(event);
- }
- } while (true); /* loop forever; we quit through an ExitToShell */
- } /* EventLoop */
-
-
- #pragma segment Main
- void main()
- {
- UnloadSeg(_DataInit); /* note that _DataInit must not be in Main! */
- MaxApplZone(); /* expand the heap so code segments load at the top */
-
- InitUFailure();
-
- Initialize(); /* initialize the program */
- UnloadSeg(Initialize); /* note that Initialize must not be in Main! */
-
- EventLoop(); /* call the main event loop */
- } /* main */
-